﻿//-----------------------------------------------------------------------
// <copyright file="WizardFormTemplate.cs" company="Microsoft Corporation">
//     Copyright (c) Microsoft Corporation 2011. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace Internal.TeamFoundationServer.Submit
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Windows.Forms;
    using Properties;

    /// <summary>
    /// StartWizard class.
    /// </summary>
    internal partial class WizardFormTemplate : Form
    {
        /// <summary>
        /// Control Stack, to manage navigation.
        /// </summary>
        private readonly Stack<WizardControlTemplate> controlStack = new Stack<WizardControlTemplate>();

        /// <summary>
        /// Initializes a new instance of the <see cref="WizardFormTemplate"/> class.
        /// </summary>
        internal WizardFormTemplate()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Gets the BottomToolbar object.
        /// </summary>
        protected GroupBox BottomToolbar
        {
            get { return this.groupBoxToolbar; }
        }

        /// <summary>
        /// Gets the GroupBoxContent object.
        /// </summary>
        protected Panel GroupBoxContent
        {
            get { return this.groupBoxContent; }
        }

        /// <summary>
        /// Opens a new Control that follows the wizard process.
        /// </summary>
        /// <param name="userControl">User control to open.</param>
        internal void OpenControl(WizardControlTemplate userControl)
        {
            try
            {
                Cursor.Current = Cursors.WaitCursor;

                Debug.Assert(!this.controlStack.Contains(userControl), "BUGBUG: UserControl already exists.");

                // Connect Events
                userControl.ChangeContinueButtonEnabled += enabled =>
                                                               {
                                                                   this.btnNext.Enabled = enabled;
                                                               };

                userControl.OpenControl += this.OpenControl;

                userControl.GoHomeRequested += this.UserControlGoHomeRequested;

                this.controlStack.Push(userControl);
                this.groupBoxContent.Controls.Add(userControl);
                this.ShowControl(userControl, null);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        /// <summary>
        /// UserControlGoHomeRequested event.
        /// </summary>
        /// <param name="action">Action object.</param>
        private void UserControlGoHomeRequested(object action)
        {
            while (this.controlStack.Count > 1)
            {
                using (var currentUserControl = this.controlStack.Pop())
                {
                    // Remove current control.
                    Debug.Assert(currentUserControl != null, "CurrentUserControl should never be null");
                    this.groupBoxContent.Controls.Remove(currentUserControl);
                }
            }

            // Get The control that should visible.
            var homeControl = this.controlStack.Peek();

            // Activate old control back to screen.
            Debug.Assert(homeControl != null, "HomeControl should never be null");
            this.ShowControl(homeControl, action);
        }

        /// <summary>
        /// Cancel button event.
        /// </summary>
        /// <param name="sender">Object sender.</param>
        /// <param name="e">Event arguments object.</param>
        private void BtnCancelClick(object sender, EventArgs e)
        {
            this.Dispose();
        }

        /// <summary>
        /// Back button event.
        /// </summary>
        /// <param name="sender">Object sender.</param>
        /// <param name="e">Event arguments object.</param>
        private void BtnBackClick(object sender, EventArgs e)
        {
            using (var currentUserControl = this.controlStack.Pop())
            {
                // Get The control that should visible.
                var oldUserControl = this.controlStack.Peek();

                // Remove current control.
                Debug.Assert(currentUserControl != null, "CurrentUserControl should never be null");
                this.groupBoxContent.Controls.Remove(currentUserControl);

                // Activate old control back to screen.
                Debug.Assert(oldUserControl != null, "OldUserControl should never be null");
                this.ShowControl(oldUserControl, null);
            }
        }

        /// <summary>
        /// Continue button event.
        /// </summary>
        /// <param name="sender">Object sender.</param>
        /// <param name="e">Event arguments object.</param>
        private void BtnNextClick(object sender, EventArgs e)
        {
            try
            {
                var currentUserControl = this.controlStack.Peek();
                Debug.Assert(currentUserControl != null, "CurrentUserControl should never be null");
                currentUserControl.NextStep();
            }
            catch (Exception err)
            {
                MessageBox.Show(
                    err.Message,
                    Resources.UnhandledException,
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error,
                    MessageBoxDefaultButton.Button1,
                    MessageBoxOptions.RightAlign & MessageBoxOptions.RtlReading);

                // Send Exception to developer.
                Utilities.ReportException(err);
                throw;
            }
        }

        /// <summary>
        /// ShowControl method.
        /// </summary>
        /// <param name="userControl">USer Control to show.</param>
        /// <param name="action">Action object.</param>
        private void ShowControl(WizardControlTemplate userControl, object action)
        {
            bool backButtonEnabled;
            bool nextButtonEnabled;
            string continueButtonCaption;

            userControl.UpdateWindow(this.lblTitle, this.lblDescription, out backButtonEnabled, out nextButtonEnabled, out continueButtonCaption, action);
            this.btnBack.Enabled = backButtonEnabled;
            this.btnNext.Enabled = nextButtonEnabled;

            Debug.Assert(!string.IsNullOrEmpty(continueButtonCaption), "BUGBUG Next button caption should never be null or empty.");
            this.btnNext.Text = continueButtonCaption;

            userControl.BringToFront();
        }
    }
}
